package com.launch.carmanager.common.utils;

import android.os.Handler;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 
 * @ClassName: TimerTaskUtils 
 * @Description: TODO(timerTask 的管理工具)
 * @author jihu 
 * @date 2016年3月23日 下午12:27:50 
 *
 */
public class TimerTaskUtils {

	/** timer运行的集合 */
	@SuppressWarnings("rawtypes")
	private static Map<String, TimerZone> timerZones = new android.support.v4.util.ArrayMap<>();

	private TimerTaskUtils() {
	}

	/**
	 * 只执行一次
	 * @param class1
	 * @param delay
	 * @param runnable
	 */
	public static void startOneTime(String class1, long delay, Runnable runnable) {
		startTimer(class1, delay, 0, runnable, null);
	}

	/**
	 * 只执行一次
	 * @param class1
	 * @param delay
	 * @param runnable
	 * @param handler
	 */
	public static void startOneTime(String class1, long delay, Runnable runnable, Handler handler) {
		startTimer(class1, delay, 0, runnable, handler);
	}

	/**
	 *
	 * @Title: startTimer
	 * @Description: TODO(同期性的执行, 马上开始执行, 然后每隔多长时间继续执行)
	 * @param class1 存放集合的key
	 * @param period 多久执行一次
	 * @param runnable 回调
	 * @return void
	 */
	@SuppressWarnings("rawtypes")
	public static void startTimer(String class1, long period, final Runnable runnable) {
		startTimer(class1, period, runnable, null);
	}

	/**
	 *
	 * @Title: startTimer
	 * @Description: TODO(同期性的执行, 马上开始执行, 然后每隔多长时间继续执行)
	 * @param class1 存放集合的key
	 * @param period 多久执行一次
	 * @param runnable 回调
	 * @param handler 可切回到主线程
	 * @return void
	 */
	public static void startTimer(String class1, long period, Runnable runnable, Handler handler) {
		startTimer(class1, 0, period, runnable, handler);
	}

	@SuppressWarnings("rawtypes")
	public static void startTimer(String class1, long delay, long period, Runnable runnable) {
		startTimer(class1, delay, period, runnable, null);
	}

	/**
	 *
	 * @Title: startTimer
	 * @Description:
	 * 		(如果delay=0，period>0则同期性执行, 马上开始执行, 然后每隔period时间继续执行
	 *      如果delay>0, period>0 则同期性执行, 第一次隔delay时间开始执行, 然后每隔period时间继续执行
	 *      如果delay>0, period=0则只执行一次,隔delay时间执行
	 *      否则其它情况会抛异常)
	 * @param class1 存放集合的key
	 * @param delay 第一次多久后开始执行
	 * @param period 以后每次多久执行一次
	 * @param runnable 回调
	 * @param handler 可切回到主线程执行
	 * @return void
	 */
	public synchronized static void startTimer(String class1, long delay, long period, Runnable runnable, Handler handler) {
		if(delay==0 && period==0) {
			throw new IllegalArgumentException("delay and period can not be equal to 0 at the same time");
		}
		if (timerZones.containsKey(class1)) {
			stopTimer(class1);
		}
		TimerZone timerZone = new TimerZone();
		timerZone.delay = delay;
		timerZone.period = period;
		timerZones.put(class1, timerZone);
		timerZone.startTimer(runnable, handler);
	}

	/**
	 *
	 * @Title: stopTimer
	 * @Description: TODO(移除并停止指定key的定时器)
	 * @param @param timerId 可以支持传多个key
	 * @return void
	 */
	@SuppressWarnings("rawtypes")
	public static void stopTimer(String... class2) {
		if (class2 != null && class2.length > 0) {
			for (String class1 : class2) {
				stopTimer(class1);
			}
		}
	}

	/**
	 *
	 * @Title: stopTimer
	 * @Description: TODO(移除并停止指定key的定时器,此方法同步,避免同一个key同时执行此方法)
	 * @param @param timerId
	 * @return void
	 */
	@SuppressWarnings("rawtypes")
	private synchronized static void stopTimer(String class1) {
		if (timerZones.containsKey(class1)) {
			TimerZone timerZone = timerZones.remove(class1);
			if (timerZone != null) {
				timerZone.stopTimer();
			}
		}
	}

	/**
	 * 停止掉所有的timer 注意:主要在退出程序的时候调用,不要在其他的地方调用，防止停掉别人写的timer
	 */
	@SuppressWarnings("rawtypes")
	public synchronized static void stopAllTimer() {
		if (timerZones.isEmpty())
			return;
		Set<String> collection = timerZones.keySet();
		Iterator<String> iterator = collection.iterator();
		while (iterator.hasNext()) {
			String class1 = iterator.next();
			if (timerZones.containsKey(class1)) {
				TimerZone timerZone = timerZones.get(class1);
				timerZone.stopTimer();
			}
			iterator.remove();
		}
	}

	static class TimerZone {
		Timer timer;
		TimerTask timerTask;
		long delay, period;

		private void startTimer(final Runnable runnable, final Handler handler) {
			if (runnable == null)
				throw new NullPointerException("call back is not null");
			stopTimer();
			timer = new Timer();
			timerTask = new TimerTask() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(handler!=null) {
						handler.post(runnable);
					} else {
						runnable.run();
					}
				}
			};
			if(period==0) {
				//执行一次
				timer.schedule(timerTask, delay);
			} else {
				//同性执行
				timer.schedule(timerTask, delay, period);
			}
		}

		private void stopTimer() {
			if (timerTask != null) {
				timerTask.cancel();
				timerTask = null;
			}
			if (timer != null) {
				timer.cancel();
				timer.purge();
				timer = null;
			}
		}

	}

}